package shark.permission.metadata;

import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import shark.permission.service.ISysPermissionService;
import shark.permission.spi.entity.SysPermission;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
@Component
public class SharkInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource, ApplicationContextAware {

    @Autowired
    private ISysPermissionService permissionService;

    private Map<String, List<SysPermission>> permissionMap =new HashMap<>();

    private HashMap<String, Collection<ConfigAttribute>> map = new HashMap<>();


    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
        List<ConfigAttribute> configAttributes = new ArrayList<>();
        /**
         * 通配符
         *    ? (匹配任何单字符)
         *    *（匹配0或者任意数量的字符）
         *    **（匹配0或者更多的目录）
         */
        // 如路由匹配不满足使用，可重写RequestMatcher接口扩展匹配规则
        AntPathRequestMatcher matcher;
        for (Map.Entry<String, Collection<ConfigAttribute>> entry : map.entrySet()) {
            for (ConfigAttribute configuration : entry.getValue()){
                matcher = new AntPathRequestMatcher(configuration.getAttribute());
                if (matcher.matches(request)) {
                    configAttributes.add(new SecurityConfig(entry.getKey()));
                }
            }
        }
        return configAttributes;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

    public void loadResource(){
        this.permissionMap = permissionService.getAuthorize();
        for (Map.Entry<String, List<SysPermission>> entry : permissionMap.entrySet()){
            Collection<ConfigAttribute> array = new ArrayList<>();
            for (SysPermission resource : entry.getValue()) {
                ConfigAttribute cfg = new SecurityConfig(resource.getUrl());
                array.add(cfg);
            }
            map.put(entry.getKey(),array);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO 需要增加权限刷新，使用mq刷新
        this.loadResource();
    }
}
